import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import '../errors/exceptions.dart';
import 'api_endpoints.dart';

/// HTTP方法枚举
enum HttpMethod { get, post, put, delete, patch }

/// HTTP客户端
class HttpClient {
  static final HttpClient _instance = HttpClient._internal();
  factory HttpClient() => _instance;
  HttpClient._internal();

  final http.Client _client = http.Client();
  
  // 默认超时时间
  static const Duration _defaultTimeout = Duration(seconds: 15);
  
  /// 请求头
  Map<String, String> _headers = {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  };

  /// 设置授权令牌
  void setAuthToken(String token) {
    _headers['Authorization'] = 'Bearer $token';
  }

  /// 移除授权令牌
  void removeAuthToken() {
    _headers.remove('Authorization');
  }

  /// 添加自定义请求头
  void addHeader(String key, String value) {
    _headers[key] = value;
  }

  /// 执行GET请求
  Future<dynamic> get(
    String url, {
    Map<String, dynamic>? queryParameters,
    Duration timeout = _defaultTimeout,
  }) async {
    return _sendRequest(
      HttpMethod.get,
      url,
      queryParameters: queryParameters,
      timeout: timeout,
    );
  }

  /// 执行POST请求
  Future<dynamic> post(
    String url, {
    dynamic body,
    Map<String, dynamic>? queryParameters,
    Duration timeout = _defaultTimeout,
  }) async {
    return _sendRequest(
      HttpMethod.post,
      url,
      body: body,
      queryParameters: queryParameters,
      timeout: timeout,
    );
  }

  /// 执行PUT请求
  Future<dynamic> put(
    String url, {
    dynamic body,
    Map<String, dynamic>? queryParameters,
    Duration timeout = _defaultTimeout,
  }) async {
    return _sendRequest(
      HttpMethod.put,
      url,
      body: body,
      queryParameters: queryParameters,
      timeout: timeout,
    );
  }

  /// 执行DELETE请求
  Future<dynamic> delete(
    String url, {
    dynamic body,
    Map<String, dynamic>? queryParameters,
    Duration timeout = _defaultTimeout,
  }) async {
    return _sendRequest(
      HttpMethod.delete,
      url,
      body: body,
      queryParameters: queryParameters,
      timeout: timeout,
    );
  }

  /// 执行PATCH请求
  Future<dynamic> patch(
    String url, {
    dynamic body,
    Map<String, dynamic>? queryParameters,
    Duration timeout = _defaultTimeout,
  }) async {
    return _sendRequest(
      HttpMethod.patch,
      url,
      body: body,
      queryParameters: queryParameters,
      timeout: timeout,
    );
  }

  /// 发送请求
  Future<dynamic> _sendRequest(
    HttpMethod method,
    String url, {
    dynamic body,
    Map<String, dynamic>? queryParameters,
    Duration timeout = _defaultTimeout,
  }) async {
    try {
      // 构建完整URL
      final uri = _buildUri(url, queryParameters);
      
      // 记录请求信息
      _logRequest(method, uri, body);

      // 构建请求体
      final jsonBody = body != null ? jsonEncode(body) : null;

      // 发送请求
      final response = await _performRequest(method, uri, jsonBody, timeout);
      
      // 记录响应信息
      _logResponse(response);

      // 处理响应
      return _processResponse(response);
    } on TimeoutException {
      throw NetworkException('请求超时，请稍后重试');
    } catch (e) {
      if (e is ServerException || e is UnauthorizedException) {
        rethrow;
      }
      throw NetworkException('网络请求失败: ${e.toString()}');
    }
  }

  /// 构建URI
  Uri _buildUri(String url, Map<String, dynamic>? queryParameters) {
    final uri = Uri.parse(url);
    if (queryParameters != null) {
      return uri.replace(
        queryParameters: queryParameters.map(
          (key, value) => MapEntry(key, value.toString()),
        ),
      );
    }
    return uri;
  }

  /// 执行HTTP请求
  Future<http.Response> _performRequest(
    HttpMethod method,
    Uri uri,
    String? body,
    Duration timeout,
  ) async {
    switch (method) {
      case HttpMethod.get:
        return _client.get(uri, headers: _headers).timeout(timeout);
      case HttpMethod.post:
        return _client.post(uri, headers: _headers, body: body).timeout(timeout);
      case HttpMethod.put:
        return _client.put(uri, headers: _headers, body: body).timeout(timeout);
      case HttpMethod.delete:
        return _client.delete(uri, headers: _headers, body: body).timeout(timeout);
      case HttpMethod.patch:
        return _client.patch(uri, headers: _headers, body: body).timeout(timeout);
    }
  }

  /// 处理响应
  dynamic _processResponse(http.Response response) {
    final statusCode = response.statusCode;
    final responseBody = _parseResponseBody(response);

    if (statusCode >= 200 && statusCode < 300) {
      return responseBody;
    } else if (statusCode == 401) {
      throw UnauthorizedException('未授权访问，请重新登录', code: statusCode.toString());
    } else if (statusCode == 403) {
      throw UnauthorizedException('权限不足，无法访问', code: statusCode.toString());
    } else if (statusCode == 404) {
      throw ServerException('资源未找到', code: statusCode.toString());
    } else if (statusCode >= 500) {
      throw ServerException('服务器错误，请稍后重试', code: statusCode.toString());
    } else {
      final errorMessage = responseBody is Map 
          ? responseBody['message'] ?? '请求失败'
          : '请求失败';
      throw ServerException(errorMessage, code: statusCode.toString(), details: responseBody);
    }
  }

  /// 解析响应体
  dynamic _parseResponseBody(http.Response response) {
    if (response.body.isEmpty) {
      return {};
    }
    try {
      return jsonDecode(response.body);
    } catch (e) {
      return response.body;
    }
  }

  /// 记录请求
  void _logRequest(HttpMethod method, Uri uri, dynamic body) {
    if (kDebugMode) {
      print('===> ${method.toString().toUpperCase()} $uri');
      print('Headers: $_headers');
      if (body != null) {
        print('Body: $body');
      }
    }
  }

  /// 记录响应
  void _logResponse(http.Response response) {
    if (kDebugMode) {
      print('<== ${response.statusCode} ${response.request?.url}');
      print('Body: ${response.body}');
    }
  }
} 